package com.iwhalecloud.bss.kite.cucc.service.order;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.inf.IInfServiceBus;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IOrderSignService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ISceneCommitService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.inf.InfServContextDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalDcPublicConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalInfConsts;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.IKitePosServiceHandler;
import com.iwhalecloud.bss.kite.cucc.service.route.InfServParamUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.zsmart.core.util.JsonUtil;

@Service
public class OrderSignService implements IOrderSignService {

    @Autowired
    private ISceneCommitService sceneCommitService;

    @Autowired
    private IInfServiceBus infService;

    @Autowired
    private IKitePosServiceHandler posServiceHandler;

    @Override
    public DataResult<String> overOrderTask(String sceneInstId, String staffId, String orgId, String worksheetId,String taskCode, String taskId, String dealResult, String failReason,
        Boolean checkAccountModule, Boolean checkContractModule, CuccContextCustDTO custDto) {
        Map<String, Object> updateData = null;
        KitePosDTO posDto = posServiceHandler.deal(sceneInstId, staffId, orgId, custDto, false, false, null);
        Map<String, Object> businessData = KiteMapUtils.beanToMap(posDto);
        if (KiteStringUtils.equalsAny(dealResult, "ORDER_START_RENT", "ORDER_STOP_RENT")) {
            Map<String, Object> rentFlowData = dealSpecialData(sceneInstId, taskCode, dealResult);
            if (!rentFlowData.isEmpty() && rentFlowData.containsKey("flowData")) {
                businessData.put("flowData", rentFlowData.get("flowData"));
            }
        }
        DcPublic dcPublic = DcPublicCache.get(LocalDcPublicConsts.DC_20201208001, taskCode);
        if (!KiteObjectUtils.isEmpty(dcPublic) && !KiteStringUtils.equals(
            SpringUtil.getBean(IQuerySceneInstService.class).getExtParameterValue(sceneInstId, "batchNode"), "T")) {
            sceneCommitService.commitModifyScene(sceneInstId, staffId, orgId, custDto, posDto);
        }
        //工单完成接口也送全量节点
        updateData = businessData;
        /* 订单中心配套改造,归集后的转单报文中实例ID不替换为订单中心的ID
        DcPublic dcPublic = DcPublicCache.get(LocalDcPublicConsts.DC_20201208001, taskCode);
        KitePosDTO posDto = posServiceHandler.deal(sceneInstId, staffId, orgId, custDto, false, false);
        if (!KiteObjectUtils.isEmpty(dcPublic)) {
            sceneCommitService.commitModifyScene(sceneInstId, staffId, orgId, custDto, posDto);
        }
        //替换goods节点的InstanceId为订单中心返回的值
        CuccPosServiceUtils.replaceGoodsInstanceId(sceneInstId, posDto);
        Map<String, Object> updateData = null;
        if (KiteStringUtils.equalsAny(dealResult, "ORDER_START_RENT", "ORDER_STOP_RENT")) {
            updateData = dealSpecialData(sceneInstId, taskCode, dealResult);
            if(KiteMapUtils.isNotEmpty(updateData)){
                Map attrs = new HashMap();
                attrs.put("attrs", posDto.getOrder().getAttrs());
                updateData.put("order", attrs);
                List<KitePosGoodsDTO> goods = new ArrayList<>();
                posDto.getGoods().forEach(posGood -> {
                    KitePosGoodsDTO good = new KitePosGoodsDTO();
                    KiteBeanUtils.copyProperties(posGood, good, "userInstId", "accountInstId", "payRelation", "products");
                    goods.add(good);
                });
                updateData.put("goods", goods);
                updateData.put("contract", posDto.getContract());
            }
        }
        if ("ORDER_SIGNED".equals(dealResult)) {
            //order.attachments中不允许含有uploadTime,先只送attrs
            KitePosOrderDTO originOrder = posDto.getOrder();
            KitePosOrderDTO order = new KitePosOrderDTO();
            order.setAttrs(originOrder.getAttrs());
            posDto.setOrder(order);
            Map<String, Object> businessData = KiteMapUtils.beanToMap(posDto);
            //去除request节点
            businessData.remove("request");
            //payRelation.is_default要送字符串
            List<KitePosGoodsDTO> goods = (List<KitePosGoodsDTO>) businessData.get("goods");
            if (KiteListUtils.isNotEmpty(goods)) {
                List goodsList = new ArrayList();
                goods.stream().forEach(good -> {
                    Map<String, Object> goodsMap = KiteMapUtils.beanToMap(good);
                    List<KitePosGoodsPayRealtionDTO> payRelations = good.getPayRelation();
                    if (KiteListUtils.isNotEmpty(payRelations)) {
                        List targetList = new ArrayList<>();
                        payRelations.forEach(payRelation -> {
                            Map<String, Object> payRelationMap = KiteMapUtils.beanToMap(payRelation);
                            payRelationMap.put("isDefault",KiteMapUtils.getStrValue(payRelationMap, "isDefault"));
                            targetList.add(payRelationMap);
                        });
                        goodsMap.put("payRelation", targetList);
                        goodsList.add(goodsMap);
                    }
                });
                businessData.put("goods", goodsList);
            }
            //user.attrs节点不传type
            List<KitePosUserDTO> users = (List<KitePosUserDTO>) businessData.get("users");
            if (KiteListUtils.isNotEmpty(users)) {
                users.forEach(user -> {
                    List targetProdAttrList = new ArrayList<>();
                    user.getAttrs().stream().forEach(attr -> {
                        KitePosAttrDTO attrDTO = new KitePosAttrDTO();
                        KiteBeanUtils.copyProperties(attr, attrDTO, "type");
                        targetProdAttrList.add(attrDTO);
                    });
                    user.setAttrs(targetProdAttrList);
                });
            }
            updateData = businessData;
        }
        */
        Map<String, String> otherData = null;
        if ("AUDIT_NOT_APPROVED".equals(dealResult) && !KiteStringUtils.isEmpty(failReason)) {
            otherData = new HashMap<>();
            otherData.put("failReason", failReason);
        }
        // 调接口
        Map<String, Object> respMap = infService.endWorkSheetTask(worksheetId, taskCode, taskId, dealResult, staffId, updateData, otherData);
        Map<String, Object> uniBssBodyRespMap = KiteMapUtils.getValue(respMap, "UNI_BSS_BODY");
        Map<String, Object> endWorkSheetTaskRspMap = KiteMapUtils.getValue(uniBssBodyRespMap, "END_WORK_SHEET_TASK_RSP");
        if (KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"))) {
            return ErrorConsts.SUCCESS.getResult("结束工单任务处理成功", ErrorConsts.SUCCESS.getCode());
        }
        else {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(endWorkSheetTaskRspMap, "message"), KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"));
        }
    }

    private  Map<String, Object> dealSpecialData(String sceneInstId, String taskCode, String dealResult) {
        Map<String, Object> updateData = new HashMap<>();
        try {
            IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
            Map<String, Object> extParameter = querySceneInstService.getExtParameter(sceneInstId);
            Map<String, Object> worksheetData = (Map<String, Object>) extParameter.get("worksheetData");
            Map<String, Object> flowData = new HashMap();
            List<Map<String, Object>> attrList = new ArrayList<>();

            String[] fieldNames;
            if ("ORDER_STOP_RENT".equals(dealResult)) {
                fieldNames = new String[]{"REC10033", "REC_10046", "REC10034"};
            } else {
                fieldNames = new String[]{"REC_10057", "REC_10046", "REC_20004", "REC_20005"};
            }

            KiteAttr kiteAttr;
            Map<String, Object> attr;
            for (String fieldName : fieldNames) {
                kiteAttr = querySceneInstService.getCommonAttr(sceneInstId, fieldName);
                if (KiteObjectUtils.isEmpty(kiteAttr)) {
                    continue;
                }

                // 起止租时间带上时分秒
                if ("REC_10057".equals(fieldName)) {
                    kiteAttr.setValue(kiteAttr.getValue() + " 00:00:00");
                } else if ("REC10033".equals(fieldName)) {
                    kiteAttr.setValue(kiteAttr.getValue() + " 23:59:59");
                }

                attr = new HashMap();
                attr.put("groupId","");
                attr.put("groupType","0");
                attr.put("code", kiteAttr.getFieldName());

                //附件处理
                if ("REC_10046".equals(kiteAttr.getFieldName()) && KiteStringUtils.isNotEmpty(kiteAttr.getValue())) {
                    JSONArray arrs = JSONArray.parseArray(kiteAttr.getValue());
                    JSONObject obj = (JSONObject) arrs.get(0);
                    String url = (String) obj.get("attachmentUrl");
                    attr.put("value", url);
                } else {
                    attr.put("value", kiteAttr.getValue());
                }
                attrList.add(attr);
            }

            flowData.put("flowValue", JsonUtil.list2Json(attrList));
            flowData.put("flowDataId","");
            flowData.put("orderId",KiteMapUtils.getStrValue(worksheetData,"orderId"));
            flowData.put("flowKey", taskCode);
            flowData.put("taskId", KiteMapUtils.getStrValue(worksheetData,"taskId"));
            List<Map<String, Object>> flowDataList = new ArrayList<>();
            flowDataList.add(flowData);
            updateData.put("flowData",flowDataList);
        }catch (Exception e){
            return new HashMap<>();
        }
        return updateData;
    }

    @Override
    public DataResult<String> overOrderTaskSpecial(String sceneInstId, String staffId, String orgId, String worksheetId, String taskCode, String taskId, String dealResult, String failReason,
                                                   Boolean checkAccountModule, Boolean checkContractModule, CuccContextCustDTO custDto) {
        KitePosDTO posDto = null;
        Map<String, String> otherData = null;
        if ("AUDIT_NOT_APPROVED".equals(dealResult) && !KiteStringUtils.isEmpty(failReason)) {
            otherData = new HashMap<>();
            otherData.put("failReason", failReason);
        }
        // 调接口
        Map<String, Object> respMap = infService.endWorkSheetTask(worksheetId, taskCode, taskId, dealResult, staffId, posDto, otherData);
        Map<String, Object> uniBssBodyRespMap = KiteMapUtils.getValue(respMap, "UNI_BSS_BODY");
        Map<String, Object> endWorkSheetTaskRspMap = KiteMapUtils.getValue(uniBssBodyRespMap, "END_WORK_SHEET_TASK_RSP");
        if (KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"))) {
            return ErrorConsts.SUCCESS.getResult("结束工单任务处理成功", ErrorConsts.SUCCESS.getCode());
        } else {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(endWorkSheetTaskRspMap, "message"), KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"));
        }
    }

    @Override
    public DataResult<String> overOrderTaskMerge(String sceneInstId, String staffId, String orderId, String worksheetId, String taskCode,
                                                 String taskId, String dealResult, String failReason, CuccContextCustDTO custDto, Object updateData) {
        Map<String, Object> respMap = infService.endWorkSheetTask(worksheetId, taskCode, taskId, dealResult, staffId, updateData, null);
        Map<String, Object> uniBssBodyRespMap = KiteMapUtils.getValue(respMap, "UNI_BSS_BODY");
        Map<String, Object> endWorkSheetTaskRspMap = KiteMapUtils.getValue(uniBssBodyRespMap, "END_WORK_SHEET_TASK_RSP");
        if (KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"))) {
            return ErrorConsts.SUCCESS.getResult("结束工单任务处理成功", ErrorConsts.SUCCESS.getCode());
        }
        else {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(endWorkSheetTaskRspMap, "message"), KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"));
        }
    }

    @Override
    public DataResult<String> overOrderTaskBatch(String sceneInstId, String staffId, String orgId,
        String worksheetId, String taskCode, String taskId, String dealResult, String failReason,
        CuccContextCustDTO custDto, String curOfferInstId) {
        InfServContextDTO context = InfServParamUtils.genSceneCommit(sceneInstId, staffId, orgId, custDto,
            false, false, curOfferInstId);
        Map<String, Object> updateData;
        KitePosDTO posDto = posServiceHandler.deal(context);
        Map<String, Object> businessData = KiteMapUtils.beanToMap(posDto);
        if (KiteStringUtils.equalsAny(dealResult, "ORDER_START_RENT", "ORDER_STOP_RENT")) {
            Map<String, Object> rentFlowData = dealSpecialData(sceneInstId, taskCode, dealResult);
            if (!rentFlowData.isEmpty() && rentFlowData.containsKey("flowData")) {
                businessData.put("flowData", rentFlowData.get("flowData"));
            }
        }

        // 工单完成接口也送全量节点
        updateData = businessData;

        Map<String, String> otherData = null;
        if ("AUDIT_NOT_APPROVED".equals(dealResult) && !KiteStringUtils.isEmpty(failReason)) {
            otherData = new HashMap<>();
            otherData.put("failReason", failReason);
        }
        // 调接口
        Map<String, Object> respMap =
            infService.endWorkSheetTask(worksheetId, taskCode, taskId, dealResult, staffId, updateData, otherData);
        Map<String, Object> uniBssHead = KiteMapUtils.getValue(respMap, "UNI_BSS_HEAD");
        if (!KiteStringUtils.equals(KiteMapUtils.getString(uniBssHead, "RESP_CODE"), LocalInfConsts.RESP_SUCCESS)) {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(uniBssHead, "RESP_DESC"),
                KiteMapUtils.getString(uniBssHead, "RESP_CODE"));
        }
        Map<String, Object> uniBssBodyRespMap = KiteMapUtils.getValue(respMap, "UNI_BSS_BODY");
        Map<String, Object> endWorkSheetTaskRspMap =
            KiteMapUtils.getValue(uniBssBodyRespMap, "END_WORK_SHEET_TASK_RSP");
        if (KeyConsts.SUCCESS_0.equals(KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"))) {
            return ErrorConsts.SUCCESS.getResult("结束工单任务处理成功", ErrorConsts.SUCCESS.getCode());
        } else {
            return ErrorConsts.INF_INVOKE_EXCEPTION.getResult(KiteMapUtils.getString(endWorkSheetTaskRspMap, "message"),
                KiteMapUtils.getString(endWorkSheetTaskRspMap, "status"));
        }
    }

}
